/* JUGJobs -- A Jobs Posting Application for Java Users Groups and Other Groups
 * $Id: NonStrippingHtmlScanner.java,v 1.3 2006/04/17 02:42:56 biglee Exp $
 * 
 * ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is the JUGJobs project.
 *
 * The Initial Developers of the Original Code are the members of the Triangle
 * Java User's Group in the RTP area of North Carolina.
 * Portions created by the Initial Developer are Copyright (C) 2005
 * the Initial Developers. All Rights Reserved.
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK ***** 
 */
package org.jugjobs.util;

import java.util.Stack;

public class NonStrippingHtmlScanner extends HTMLScanner {

	private boolean problemNoted;
	private StringBuffer summary;
	private int spaceRemaining;
	
	Stack tagStack;
	private String currentTag = null;
	private boolean currentTagCloser = false;
	private String currentTagParms = null;
	
	public NonStrippingHtmlScanner(String myString) {
		super(myString);
		// TODO Auto-generated constructor stub
	}

	protected void noteProblem(String problem) throws HTMLScanningException {
		problemNoted = true;

	}

	protected void text(String st) throws HTMLScanningException {
		if(spaceRemaining!=0) {
			if(spaceRemaining>=st.length()) {
				summary.append(st);
				spaceRemaining -= st.length();
			}
			else {
				summary.append(st.substring(0,spaceRemaining));
				spaceRemaining=0;
			}
			if(spaceRemaining==0) {
				summary.append("...");
			}
		}
	}

	protected void wicket() throws HTMLScanningException {
		// reset for a new tag
		currentTag = null;
		currentTagCloser = false;
		currentTagParms = "";

	}

	protected void closeWicket() throws HTMLScanningException {
		// emit the tag if it is allowed in the summary
		// (Current tag will be null if we are not in a summary tag
		// or not in a tag at all)
		if(currentTag!=null) {
			if(!currentTagCloser){
				summary.append("<");
				summary.append(currentTag);
				summary.append(" ");
				summary.append(currentTagParms);
				summary.append(">");
			}
			else {
				summary.append("<");
				summary.append("/");
				summary.append(currentTag);
				summary.append(">");
			}			
		}
		else {
			text(" ");
		}
	}

	protected void tag(String tag) throws HTMLScanningException {
		tag = tag.toUpperCase();
		// don't process tags after spaceRemaining is expended
		if(spaceRemaining >0 ) {
			// process tags -- first decide what the tag is
			boolean closer=false;
			if(tag.startsWith("/")){
				closer=true;
				tag = tag.substring(1);
			}
			// only process tags that are summary tags
			if(TextAndHtmlUtilities.getSummaryTagMap().get(tag)!=null) {
				currentTag = tag;
				currentTagCloser = closer;
				currentTagParms = "";
				if(!closer) {
					if(TextAndHtmlUtilities.getBalancingTagMap().get(tag)!=null) {
						tagStack.push(tag);
					}
				}
				else {
					if(tagStack.size()>0 && currentTag.equalsIgnoreCase((String)tagStack.peek())){
						tagStack.pop();
					}
				}
			}
		}
		else {
			currentTag = null;
		}
	}

	protected void tagParms(String parms) throws HTMLScanningException {
		// remember the parameter string for the current tag
		currentTagParms = parms;
	}
	
	public String summarize() {
		return summarize(TextAndHtmlUtilities.SUMMARY_SIZE);
	}


	public String summarize(int sumLen) {
		problemNoted = false;
		summary=new StringBuffer();
		spaceRemaining = sumLen;
		tagStack = new Stack();
		try {
			performScan();
		} catch (HTMLScanningException e) {
			return new StrippingHtmlScanner(s).summarize();
		}
		// close any tags that are still open
		while(tagStack.size()>0) {
			summary.append("</"+((String)tagStack.pop())+">");
		}
		if(problemNoted) {
			summary.append("<br />(?)");
		}
		return summary.toString();
	}

	protected boolean proceedOnError() {
		// if we are done summarizing then a parsing error makes a good place to stop
		return spaceRemaining!=0;
	}
}
